<script lang="ts" setup>
import {computed, onMounted, ref} from "vue";
import {useUserStore} from "@/stores/user";
import AddTagPopup from "@/pages/upload/components/AddTagPopup.vue";
import {IMessage} from "@/components/aw-message/message";
import type {Result} from "@/types/Result";
import type {UploadDataImage, userUploadImages} from "@/types/upload";
import {useUploadImageStore} from "@/stores/userUploadImage";
import {onLoad} from "@dcloudio/uni-app";
import {delUserImageApi, uploadAnimalImagesApi} from "@/api/upload";
import {getUserUploadCountApi} from "@/api/user";

const userStore = useUserStore()
const uploadImageStore = useUploadImageStore()
const upload = ref()
const uploadCount = ref(0)
/**
 * 获取用户剩余上传次数
 */
const getUploadCount = async () => {
  const res = await getUserUploadCountApi()
  uploadCount.value = res.data
}
onMounted(() => {
  getUploadCount()
  imageList.value = uploadImageStore.uploadData.images?.map((item, index) => {
    upload.value.updateImageTempPath(item, index)
    return {
      path: item
    }
  }) || []
})
onLoad(() => {
  uploadData.value = uploadImageStore.uploadData || {}
})
const listStyle = {
  columns: 2,
  columnGap: '20rpx',
  rowGap: '20rpx',
  padding: '10rpx',
  height: '300rpx',
  radius: '20rpx'
}
const imageFormData = {
  count: 5,
  sizeType: ['original', 'compressed'],
  compress: true,
  size: 4,
}
const imageList = ref<{ path: string, poster?: string }[]>([])
const warningMsg = ref("已自动过滤大小不符的图片")
const onSuccess = (res: Result<userUploadImages>) => {
  console.log('上传完成', res)
  loading.value = false
  if (res.code !== '1') {
    return uni.showToast({
      title: res.message || '图片上传失败',
      icon: 'error',
      duration: 2500
    })
  }
  if (res.data.haveAnimal) { // 判断是否含有动物
    filterTags(res.data.tags)
    // ai 识别到动物拼接tag
  } else {
    uploadPopup.value.open()
    warningMsg.value = "存在未识别到动物的图片，可能会影响审核结果"
  }
  const listItem = {
    path: res.data.imageUrl,
    // poster: res.data.imageUrl,
  }
  imageList.value.push(listItem)
  uploadData.value.images = imageList.value.map(item => {
    return item.path
  })
  //上传成功后，手动触发上传下一个
}

// 用户清空待上传数据
const onClearUpload = () => {
  clearUpload.value.open()
}

/**
 * 本地保存待上传数据
 */
const onSaveUploadData = () => {
  uploadImageStore.uploadData = uploadData.value
  console.log(uploadData.value)
  IMessage({
    showIcon: true,
    type: "success",
    content: "已保存到本地"
  })
}
/**
 * 用户点击上传
 */
const onCheckUpload = () => {
  if (!checkUpload.value) {
    return uni.showToast({
      title: '请选择标签',
      icon: 'none'
    })
  }
  uploadImage.value.open()
}

const suggestTags = ref<string[]>([])
const uploadData = ref<UploadDataImage>({} as UploadDataImage)
const tagsPopup = ref()
const checkUpload = computed(() => {
  return uploadData.value.tags?.length > 0 && uploadData.value.images?.length > 0
})
const showTagPopup = () => {
  tagsPopup.value.open()
}
/**
 * 删除tag
 * @param index 被删除的索引
 */
const onDeleteTag = (index: number) => {
  // 删除
  uploadData.value?.tags.splice(index, 1)
}
/**
 * 添加tag
 * @param tag tag值
 */
const onAddTag = (tag: string) => {
  if (!uploadData.value.tags) {
    return uploadData.value.tags = [tag]
  }
  if (uploadData.value.tags.includes(tag)) {
    return uni.showToast({title: '不能添加两个相同的标签', icon: 'none', duration: 1500})
  }
  uploadData.value.tags.push(tag)
  uni.hideKeyboard()
}
// 点击取消
const onCancelTag = () => {
  tagsPopup.value.close()
}
/**
 * 点击确定
 */
const onConfirmTag = () => {
  tagsPopup.value.close()
}
/**
 * 当图片大小超出限制
 */
type imageInfo = {
  path: string,
  size: number
}
const uploadPopup = ref()
const onImageOversize = (info: imageInfo) => {
  warningMsg.value = "已自动过滤大小不符的图片"
  uploadPopup.value.open()
}
const onClickSuggestion = (content: string, index: number) => {
  if (uploadData.value.tags?.length >= 8) {
    return uni.showToast({title: '标签数已达上限', icon: 'none', duration: 1500})
  }
  // 移除该建议tag
  suggestTags.value.splice(index, 1)
  onAddTag(content)
}
/**
 * 点击已本地选择好的图片进行编辑
 * @param item 图片信息
 * @param index 图片索引
 */
type imageListItem = {
  item: {
    path: string,
    poster?: string
  }
  index: number
}
const handleEditImage = (item: imageListItem) => {
  // #ifdef H5
  return IMessage({
    content: 'App内可享图片编辑功能',
    showIcon: true,
    type: 'warning'
  })
  /*  const filName = Date.now() + '.jpg'
    // H5端base64转为path
    item.item.path = base64ToFile(item.item.path, filName)*/
  // #endif
  // 跳转至图片裁剪页面
  uni.navigateTo({
    url: '/subPkg/imageCut/imageCut?imageSrc=' + item.item.path + '&index=' + item.index
  })
}

/**
 * 用户过滤上传图片后的标签过滤
 * @param tags
 */
const filterTags = (tags: string[]) => {
  let tempTags: string[] = uploadData.value.tags || []
  // 判断之前是否有tag
  if (suggestTags.value?.length === 0 && tempTags.length === 0) {
    suggestTags.value = tags
  } else if (suggestTags.value?.length === 0 && tempTags.length > 0) {
    // 推荐标签不能与用户已选标签重复
    suggestTags.value = tags.filter(tag => !tempTags.includes(tag))
  } else if (suggestTags.value?.length > 0 && tempTags.length === 0) {
    // 用户没有选择tag，则推荐标签不能重复
    suggestTags.value = [...new Set([...tags, ...suggestTags.value])]
  } else if (suggestTags.value?.length > 0 && tempTags.length > 0) {
    // 用户已选择tag，suggestTag不能与已有suggest重复，不能与用户所选重复
    // 1、先过滤
    suggestTags.value = [...new Set([...tags, ...suggestTags.value])]
        .filter(tag => !tempTags.includes(tag))
  }
}
// 监听裁剪上传图片
uni.$on('cutUploadImage', (data: { path: string, index: number }) => {
  upload.value?.updateImageTempPath(data.path, data.index)
  loading.value = true
  // 这里需要手动上传
  const task = uni.uploadFile({
    url: '/user/upload/images',
    name: 'file',
    filePath: data.path,
    timeout: 10000,
    // header: {
    //   'Avatar': userStore.userInfoData!.userID
    // },
    success(res) {
      // 判断是否上传成功
      const resultData: Result<userUploadImages> = JSON.parse(res.data)
      // uploadData.value.images[data.index] = resultData.data
      if (resultData.code !== '1') {
        return uni.showToast({
          title: resultData.message || '图片上传失败',
          icon: 'error',
          duration: 2500
        })
      }
      // 上传成功
      IMessage({
        type: 'success',
        showIcon: true,
        content: '图片修改成功',
      })
      if (resultData.data.haveAnimal) { // 判断是否含有动物
        filterTags(resultData.data.tags)
        // ai 识别到动物拼接tag
      } else {
        uploadPopup.value.open()
        warningMsg.value = "存在未识别到动物的图片，可能会影响审核结果"
      }
      imageList.value[data.index] = {
        path: resultData.data.imageUrl,
      }
      uploadData.value.images = imageList.value.map(item => {
        return item.path
      })
    },
    complete() {
      loading.value = false
    }
  })
  task.onProgressUpdate((e) => {
    progress.value = e.progress
  })
})

/**
 * 相关提醒
 */
const uploadImage = ref()
const clearUpload = ref()
const onCancelUpload = () => {
  uploadImage.value.close()
}

// 用户确认上传
const messagePopup = ref()
const onSubmit = async () => {
  console.log("确认上传")
  console.log(uploadData.value)
  uploadImage.value.close()
  uni.showLoading({
    title: '上传中...',
  })
  const res = await uploadAnimalImagesApi(uploadData.value)
  uni.hideLoading()
  if (res.code === '1') {
    messagePopup.value.open()
    onConfirmClear()  // 清空数据
    IMessage({
      content: '上传成功',
      type: 'success',
      showIcon: true
    })
  } else {
    IMessage({
      content: '上传失败',
      type: 'error',
      showIcon: true
    })
  }
}

const onCancelClear = () => {
  clearUpload.value.close()
}
// 确认删除
const onConfirmClear = () => {
  uploadData.value = {} as UploadDataImage
  uploadImageStore.uploadData = {} as UploadDataImage
  imageList.value = []
  suggestTags.value = []
  clearUpload.value.close()
}

// 骨架屏控制
const loading = ref(false)
const skeleton = [{
  type: 'line',
  num: 2,
  gap: '10px'
}]
const progress = ref(0)
const onStartUpload = () => {
  loading.value = true
}
const onProgress = (e: any) => {
  console.log(e.progress)
  progress.value = e.progress
}
const moveHandle = () => {
}


// 删除图片
const delUpload = ref()
let delIndex = 0
let delItem = {}
const onDeleteImage = (item: any, index: number) => {
  delIndex = index
  delItem = item
  delUpload.value.open()
}
const onCancelDel = () => {
  delUpload.value.close()
}
/**
 * 确认删除
 */
const onConfirmDel = () => {
  const del = imageList.value.splice(delIndex, 1)
  uploadData.value.images = imageList.value.map(item => {
    return item.path
  })
  // 这里不需要异步，如果后端删除失败前端也不做反馈
  delUserImageApi(del[0].path)
  delUpload.value.close()
}

const closeMessage = () => {
  messagePopup.value.close()
}
</script>

<template>
  <view :scroll-y="true" class="image-container">
    <view v-show="loading" class="loading" @touchmove.stop.prevent="moveHandle">
      <view class="loading-mask">
        <uv-loading-icon :show="true" :text="'正在上传'+progress+'%'" :text-color="'#fff'" :text-size="14"
                         :vertical="true"
                         inactive-color="#39c5bb"
                         mode="circle"
                         size="38"></uv-loading-icon>
      </view>
    </view>


    <view class="image-box padding-sm" style="width: 100%">
      <view class="text-gray text-bold flex justify-between align-center">
        <view :class="[uploadCount===0?'text-red':'text-black' ,'text-sm']">
          {{ uploadCount === 0 ? '本周已不能上传' : '本周剩余上传次数：' }}
          <text v-if="uploadCount!==0" class="text-red text-bold">{{ uploadCount }}</text>
        </view>
        {{ uploadData.images?.length || 0 }} / 3
      </view>
      <cl-upload ref="upload" v-model="imageList"
                 :auto-upload="true" :image-form-data="imageFormData"
                 :isPreviewImage="false"
                 :listStyle="listStyle"
                 :max="3"
                 action="/user/upload/images"
                 fileType="image"
                 useBeforeDelete
                 @beforeDelete="onDeleteImage"
                 @onImage="handleEditImage"
                 @onImageSize="onImageOversize"
                 @onProgress="onProgress"
                 @onSuccess="onSuccess"
                 @startUpload="onStartUpload">
        <template v-slot:addImg>
          <view class="flex justify-center align-center"
                style="width: 100%;height: 100%;border-radius: 8%;border: #cdcdcd 2px dashed">
            <image src="/static/add-image.png" style="width: 40%;height: 40%"></image>
          </view>

        </template>
      </cl-upload>
      <view class="flex justify-between margin-top-xl" style="width: 100%">
        <view class="text-gray" style="font-size: 10px">选择图片后点击可进行编辑</view>
        <view class="text-gray  " style="font-size: 10px">图片大小不能超过
          <text class="text-red">4MB</text>
        </view>
      </view>
    </view>
    <view style="width: 100%">
      <!--       标签   -->
      <view class="form-tag">
        <uni-collapse>
          <uni-collapse-item :border="false" :open="true" :show-animation="true" class="add-tag" title-border="none">
            <template v-slot:title>
              <view class="tag-title flex justify-between align-center">
                <text>
                  <text class="text-red" style="font-size: 14px;margin-right: 5px">*</text>
                  {{
                    uploadData.tags?.length > 0 ? `已选标签 ${uploadData.tags?.length}/8` : '添加标签'
                  }}
                </text>
                <text class="text-gray margin-left-lg" style="font-size: 10px">默认
                  <text class="text-red">第一个</text>
                  标签为标题
                </text>
              </view>
            </template>
            <view class="tag-list">
              <view v-for="item in uploadData.tags" :key="item" class="add-tag-btn">
                {{ item }}
              </view>
              <view :class="['add-tag-btn',uploadData.tags?.length>=8?'bg-disabled':'']" hover-class="add-tag-btn-hover"
                    @click="showTagPopup">
                <uni-icons :color="uploadData.tags?.length >=8?'#E4E5E7FF':'#ffffff'" size="20" type="plus"></uni-icons>
                {{ uploadData.tags?.length > 0 ? '修改标签' : '添加标签' }}
              </view>
            </view>
          </uni-collapse-item>
        </uni-collapse>
      </view>

      <!--      <view>
              <view>推荐标签</view>
            </view>-->
    </view>
    <view class="form-tag" style="width: 100%">
      <view class="add-tag">
        <view class="tag-title" style="align-self: flex-start">推荐标签</view>
        <view v-show="!loading" class="flex flex-wrap justify-start padding-sm">
          <view v-for="(item,index) in suggestTags.slice(0,15)" v-show="suggestTags" :key="item"
                :class="uploadData.tags?.length===8?'bg-disabled':''" class="add-tag-btn"
                @click="onClickSuggestion(item,index)">
            {{ item }}
          </view>
          <view v-show="suggestTags.length===0" class="text-gray">
            <view class="margin-top-sm">
              <text class="cuIcon-refresh text-bold" style="font-size: 14px"></text>
              {{ uploadData.images?.length === 0 ? '上传图片后推荐' : '暂无推荐标签' }}
            </view>
          </view>
        </view>
        <view style="width: 80%;margin-bottom: 20px;margin-top: 10px">
          <uv-skeletons :loading="loading" :skeleton="skeleton"></uv-skeletons>
        </view>
      </view>

    </view>
    <view class="image-item">
      <view class="footer">
        <view class="save margin-left-sm" hover-class="save-hover" @click="onClearUpload">
          <view class="cuIcon-refresh text-shadow text-awGreen" style="font-size: 58rpx"></view>
        </view>
        <view class="save" hover-class="save-hover" @click="onSaveUploadData">
          <view class="cuIcon-file text-shadow text-awGreen " style="font-size: 58rpx"></view>
        </view>
        <view :class="['submit', userStore?.userInfoData?
        checkUpload? ' bg-gradual-awGreen'
        : 'bg-disabled':'bg-disabled']"
              hover-class="submit-hover" @click="onCheckUpload">上传
          <text class="cuIcon-upload" style="font-size: 40rpx"></text>
        </view>
      </view>
    </view>
  </view>
  <!--  底部弹出层-->
  <uni-popup ref="tagsPopup" style="z-index: 9999" type="bottom">
    <view class="bg-white">
      <add-tag-popup :tag-list="uploadData.tags" @addTag="onAddTag" @cancel="onCancelTag" @confirm="onConfirmTag"
                     @deleteTag="onDeleteTag"></add-tag-popup>
    </view>
  </uni-popup>
  <uni-popup ref="uploadPopup" style="z-index: 9999" type="message">
    <uni-popup-message :duration="3500" type="warn">
      <view class="flex justify-center align-center text-orange" style="width: 100% ;gap: 5px">
        <text class="cuIcon-warn" style="font-size: 18px"></text>
        {{ warningMsg }}
      </view>
    </uni-popup-message>
  </uni-popup>
  <uni-popup ref="messagePopup" type="center" @touchmove.stop.prevent="moveHandle">
    <view class="flex justify-around align-center" style="width: 100%">
      <view class="flex justify-around align-center flex-column bg-white  padding-lg"
            style="width: 70%;border-radius: 5%">
        <view class="text-bold text-orange">提示</view>
        <view class="margin-tb-lg text-black text-df" style="line-height: 1.5rem">
          上传完成后需要进行审核，审核时间在1-2个工作日内完成
        </view>
        <uv-button :color="'#39c5bb'" @click="closeMessage">确定</uv-button>
      </view>
    </view>

  </uni-popup>
  <!--  上传确认-->
  <uv-modal ref="uploadImage" :closeOnClickOverlay="false" :zoom="true" title="提示">
    <template v-slot:default>
      <view class="text-df"> 上传的图片或文字内容不能违反国家法律规定，否则不但审核不会通过，还会进行
        <text class="text-red">封号</text>
        处理。
      </view>
    </template>
    <template v-slot:confirmButton>
      <view class="flex padding-sm justify-center align-center" style="width: 100%;gap: 40px">
        <button class="cu-btn round line-gray lg" @click="onCancelUpload">取消</button>
        <button class="cu-btn round bg-gradual-awGreen lg" @click="onSubmit">确定上传</button>
      </view>
    </template>
  </uv-modal>

  <!--  确认清除-->
  <uv-modal ref="clearUpload" :closeOnClickOverlay="false" :zoom="true" title="是否确认清空当前数据">
    <template v-slot:confirmButton>
      <view class="flex padding-sm justify-center align-center" style="width: 100%;gap: 40px">
        <button class="cu-btn round bg-gray lg" @click="onCancelClear">取消</button>
        <button class="cu-btn round bg-gradual-awGreen lg" @click="onConfirmClear">确定</button>
      </view>
    </template>
  </uv-modal>
  <uv-modal ref="delUpload" :closeOnClickOverlay="false" :zoom="true" title="是否删除该图片">
    <template v-slot:confirmButton>
      <view class="flex padding-sm justify-center align-center" style="width: 100%;gap: 40px">
        <button class="cu-btn round bg-gray lg" @click="onCancelDel">取消</button>
        <button class="cu-btn round bg-gradual-awGreen lg" @click="onConfirmDel">确定</button>
      </view>
    </template>
  </uv-modal>
</template>

<style lang="scss" scoped>
page {
  background-color: #f0f0f0;
}

.loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0);
  z-index: 9999;
}

.loading-mask {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 8%;
  z-index: 9999;
  width: 100px;
  height: 100px;
}

.image-container {
  width: 100%;
  padding: 20px;
  padding-bottom: 120rpx;
  display: flex;
  //height: 100vh;
  flex-direction: column;
  align-items: center;
  row-gap: 20px;
  //background: #FFFFFF;
}

.image-item {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.footer {
  z-index: 9;
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* #ifdef MP-WEIXIN */
  padding: 40rpx 20rpx 0;
  /* #endif */
  width: 100%;
  gap: 10rpx;
  position: fixed;
  bottom: 0;
  left: 0;
  padding: 40rpx 20rpx;
  backdrop-filter: blur(10px);

  .save {
    width: 80rpx;
    height: 80rpx;
    background-color: rgba(235, 249, 248, 0.8);
    border-radius: 20rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;

    image {
      width: 65%;
      height: 65%;
      object-fit: cover;
    }
  }

  .submit {
    width: 70%;
    height: 80rpx;
    border-radius: 25px;
    //margin: 20px 40rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    font-size: 40rpx;
    z-index: 9;
    opacity: 1;
    gap: 18rpx;
    box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
  }
}

.submit-hover {
  background-color: #00bf9d;
}

.bg-disabled {
  background: #c3c3c7 !important;
  color: #E4E5E7FF !important;
}

.image-box {
  border-radius: 10px;
  background: #FFFFFF;
}

// 标签样式
.form-tag {
  border-radius: 10px;
  width: 100%;
  //background-color: rgba(255, 255, 255, 0.3);
  margin-bottom: 10px;
  background: #FFFFFF !important;
  //border: #EBF9F8 1px solid;
  box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
  /* #ifdef H5 */
  //height:100px;
  /* #endif */

  .add-tag {
    display: flex;
    align-items: center;
    flex-direction: column;
    flex-wrap: wrap;

    .tag-title {
      margin-top: 5px;
      padding: 5px;
      font-size: 14px;
      color: #8d8d8d;
      opacity: 1;
    }

    .tag-list {
      display: flex;
      justify-content: flex-start;
      padding: 10px;
      align-items: center;
      flex-wrap: wrap;
      border-radius: 10px;
      /* #ifdef H5 */
      height: 120px;
      /* #endif */

      .add-tag-btn {
        position: relative;
        height: 60rpx;
        min-width: 80rpx;
        background: #39c5bb;
        border-radius: 15px;
        margin: 10px 10px 10px 0;
        display: flex;
        justify-content: center;
        align-items: center;
        color: #ffffff;
        font-size: 13px;
        z-index: 8;
        opacity: 1;
        padding: 5px 10px;
      }

      .add-tag-btn-hover {
        background-color: #3ebed3;
      }
    }

    .tag {
      margin: 8px;
    }
  }
}

.add-tag-btn {
  position: relative;
  height: 60rpx;
  min-width: 80rpx;
  background: #39c5bb;
  border-radius: 15px;
  margin: 10px 10px 10px 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #ffffff;
  font-size: 13px;
  z-index: 8;
  opacity: 1;
  padding: 5px 10px;
}
</style>
